package cn.gorit.resource.service;

import cn.gorit.common.enums.ResultEnums;
import cn.gorit.common.enums.StateEnums;
import cn.gorit.common.exception.ResourceException;
import cn.gorit.common.lang.Result;
import cn.gorit.dto.resource.DownloadDto;
import cn.gorit.entity.resource.Source;
import cn.gorit.mapper.resource.SourceMapper;
import cn.gorit.utils.StringUtils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @version v1.0
 * @Classname SourceService
 * @Description 资源服务
 * @Author CodingGorit
 * @Created on 2021/4/14 23:46
 * @IDLE IntelliJ IDEA
 **/
@Service
public class FileService {

    private final Logger log = LoggerFactory.getLogger(FileService.class);

    @Autowired
    private SourceMapper mapper;

    @Value("${oss.accessKeyId}")
    private String accessKeyId;

    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${oss.endpoint}")
    private String endpoint;

    @Value("${oss.bucketName}")
    private String bucketName;

    @Value("${oss.basepath}")
    private String BASE_PATH;


    // 上传
    public Result<Object> upload(MultipartFile file, String userId) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String result = "";
        try{
//            if (ossClient.doesBucketExist(bucketName)) {
//                log.info("您已经创建Bucket：" + bucketName + "。");
//            } else {
//                log.info("您的Bucket不存在，创建Bucket：" + bucketName + "。");
//                ossClient.createBucket(bucketName);
//            }
            SimpleDateFormat smp = new SimpleDateFormat("yyyyMMdd");
            String suffic = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().indexOf("."));
            String newFileName = smp.format(new Date()) + "_" + UUID.randomUUID().toString().replace("-","") + suffic;
            StringBuilder path = new StringBuilder();

            Source source = new Source();
            if (!suffic.equals(".mp4")) {
                // 存储的为图片
                path.append(StateEnums.SOURCE_IMAGE.getMsg());
                source.setSourceType(StateEnums.SOURCE_IMAGE.getCode());
            } else {
                // 存储视频
                path.append(StateEnums.SOURCE_VIDEO.getMsg());
                source.setSourceType(StateEnums.SOURCE_VIDEO.getCode());
            }
            path.append(newFileName);
            // 检查 newFileName 是否存在

            boolean found = ossClient.doesObjectExist(bucketName, path.toString());

            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, path.toString(), file.getInputStream());
            if (!StringUtils.isTrue(found)) {
                // 上传文件。
                ossClient.putObject(putObjectRequest);
                result = BASE_PATH + path.toString();
                // log.info("上传的地址：{}",result);
                // 执行数据库的操作， 数据库存 path，访问是 BASE_PATH + path

                source.setSourceUrl(path.toString());
                source.setSourceName(newFileName);
                source.setUserId(userId);  // 用户ID 前端传过来
                mapper.addSource(source);
            }

        } catch (Exception e){
            e.printStackTrace() ;
            return new Result<>(ResultEnums.UPLOAD_FAILED.getCode(),ResultEnums.UPDATE_FAILED.getMsg(),e.getMessage());
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
        return new Result<>(ResultEnums.UPLOAD_SUCCESS.getCode(),ResultEnums.UPLOAD_SUCCESS.getMsg(),result);
    }

    // 下载
    public void download(DownloadDto dto)  {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 创建OSSClient实例。
        String suffic = dto.getObjectPath().substring(dto.getObjectPath().indexOf("."));
        ossClient.getObject(new GetObjectRequest(bucketName, dto.getObjectPath()), new File(dto.getDownloadUrl() + "\\result" + suffic));
        // 关闭OSSClient。
        ossClient.shutdown();
    }


    // 删除 (path 即为数据库中的字段）
    public Result<Object> delete(String path) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 删除文件。如需删除文件夹，请将ObjectName设置为对应的文件夹名称。如果文件夹非空，则需要将文件夹下的所有object删除后才能删除该文件夹。
        ossClient.deleteObject(bucketName, path);
        ossClient.shutdown();
        // 数据库同步删除数据
        mapper.delete(path);
        return new Result<>(ResultEnums.DELETE_SUCCESS.getCode(),ResultEnums.DELETE_SUCCESS.getMsg(),"");
    }

    // 获取 oss 存储列表 阿里云服务器列表
    public Result<List<OSSObjectSummary>> getOssFileList(String prefix) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 创建OSSClient实例。
        // 列举文件。如果不设置KeyPrefix，则列举存储空间下的所有文件。如果设置KeyPrefix，则列举包含指定前缀的文件。
        if (StringUtils.isNotBlank(prefix)) {
            ObjectListing result = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix(prefix).withMaxKeys(50));
            List<OSSObjectSummary> sums = result.getObjectSummaries();
            // 关闭OSSClient。
            ossClient.shutdown();
            return new Result<>(ResultEnums.QUERY_SUCCESS.getCode(),ResultEnums.QUERY_SUCCESS.getMsg(),sums);
        } else {
            ListObjectsV2Result result = ossClient.listObjectsV2(bucketName);
            List<OSSObjectSummary> ossObjectSummaries = result.getObjectSummaries();
            // 关闭OSSClient。
            ossClient.shutdown();
            return new Result<>(ResultEnums.QUERY_SUCCESS.getCode(), ResultEnums.QUERY_SUCCESS.getMsg(), ossObjectSummaries);
        }
    }
}
